class Solution
{
public:
    int minMalwareSpread(vector<vector<int>> &graph, vector<int> &initial)
    {
        int n = graph.size();
        vector<int> ufs(n);
        vector<int> sizes(n, 1);
        iota(ufs.begin(), ufs.end(), 0);
        function<int(int)> find = [&](int x)
        {
            return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
        };
        auto merge = [&](int x, int y)
        {
            x = find(x);
            y = find(y);
            if (x != y)
            {
                ufs[x] = y;
                sizes[y] += sizes[x];
            }
        };
        auto size = [&](int x)
        {
            return sizes[find(x)];
        };

        for (int i = 0; i < n; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                if (graph[i][j])
                {
                    merge(i, j);
                }
            }
        }

        unordered_map<int, int> count;
        for (int i : initial)
        {
            count[find(i)]++;
        }
        int maxSize = 0;
        int result = INT_MAX;
        for (int i : initial)
        {
            if (count[find(i)] == 1)
            {
                if (size(i) > maxSize)
                {
                    maxSize = size(i);
                    result = i;
                }
                else if (size(i) == maxSize)
                {
                    result = min(result, i);
                }
            }
        }
        if (result == INT_MAX)
        {
            result = *min_element(initial.begin(), initial.end());
        }
        return result;
    }
};